在金融数据分析中,我们经常需要处理成组的相关数据。
Python提供了三种核心复合数据类型:
| 类型 | 特点 | 典型应用 |
|---|---|---|
| 列表 (List) | 可变、有序 | 股价时间序列 |
| 字典 (Dictionary) | 键值对、快速查找 | 股票信息存储 |
| 元组 (Tuple) | 不可变、安全 | 固定配置参数 |
从计算机科学角度看,三种数据类型代表了不同的抽象层次:
列表是Python中最常用的数据结构之一:
在金融应用中,列表常用于存储:
列表可以包含不同类型的元素(这是Python列表的独特优势):
'finance'、数值 8.88 可以共存关键时间复杂度:
| 操作 | 复杂度 | 说明 |
|---|---|---|
x[i] 索引访问 |
O(1) | 直接定位 |
x[a:b] 切片 |
O(k) | k为切片长度 |
len(x) |
O(1) | 内置存储长度 |
x.append() |
均摊O(1) | 动态数组扩容 |
# 创建初始投资组合(存储A股股票代码)
portfolio = ['600519.SH', '000858.SZ', '600036.SH', '000002.SZ']
# 6位数字.SH(上海)或.SZ(深圳)
# 添加新股票(末尾追加,均摊O(1))
portfolio.append('601318.SH') # 中国平安
# 移除股票(需遍历查找,O(n))
portfolio.remove('000002.SZ') # 万科A
# 输出当前持仓
print(f'当前持仓股票数量: {len(portfolio)}')
for i, stock in enumerate(portfolio, start=1):
print(f' {i}. {stock}')当前持仓股票数量: 4
1. 600519.SH
2. 000858.SZ
3. 600036.SH
4. 601318.SH
| 方法 | 功能 | 示例 |
|---|---|---|
append(x) |
末尾添加元素 | lst.append('new') |
remove(x) |
删除第一个匹配 | lst.remove('old') |
insert(i,x) |
指定位置插入 | lst.insert(0,'first') |
pop(i) |
删除并返回元素 | lst.pop(-1) |
sort() |
原地排序 | lst.sort() |
reverse() |
原地反转 | lst.reverse() |
index(x) |
查找元素位置 | lst.index('target') |
注意:append、sort、reverse 都是原地修改,返回 None。
字典是Python中最重要的数据结构之一:
字典的核心特点是键值对 (Key-Value Pair) 结构:
字典底层使用哈希表 (Hash Table) 实现:
hash(key) 计算哈希值性能对比:
| 操作 | 字典 | 列表 |
|---|---|---|
| 查找元素 | O(1) | O(n) |
| 插入元素 | O(1) | O(n) |
| 删除元素 | O(1) | O(n) |
| 遍历全部 | O(n) | O(n) |
键的要求:必须是不可变类型(int, str, tuple),不能是list或dict。
# 创建股票信息字典
stock_info = {
'code': '600519.SH',
'name': '贵州茅台',
'price': 1850.00,
'volume': 2500000
}
# 更新股价
stock_info['price'] = 1860.00
# 添加新字段(市盈率)
stock_info['pe_ratio'] = 45.5
# 检查字段是否存在
if 'market_cap' in stock_info:
print(f'市值: {stock_info["market_cap"]}')
else:
print('市值信息缺失')
# 批量更新
stock_info.update({'price': 1870.00, 'volume': 2600000})
print(stock_info)市值信息缺失
{'code': '600519.SH', 'name': '贵州茅台', 'price': 1870.0, 'volume': 2600000, 'pe_ratio': 45.5}
| 方法 | 功能 | 示例 |
|---|---|---|
d[key] |
获取值(不存在报错) | d['name'] |
d.get(key, default) |
安全获取值 | d.get('name', '未知') |
d[key] = val |
设置/更新值 | d['price'] = 100 |
d.update(other) |
批量更新 | d.update({...}) |
key in d |
检查键是否存在 | 'name' in d |
d.keys() |
获取所有键 | 返回视图对象 |
d.values() |
获取所有值 | 返回视图对象 |
d.items() |
获取所有键值对 | 返回视图对象 |
keys()、values()、items() 返回的是视图对象:
共有键: {'c', 'b'}
A独有键: {'a'}
视图对象支持集合运算:&(交集)、|(并集)、-(差集)
元组是不可变的 (Immutable) 有序序列。
不可变性带来的优势:
切片规则 tup[start:end]:
start 索引,不包含 end 索引tup[1:3] → 索引1和索引2的元素标准元组只能通过索引访问,代码可读性差。命名元组解决了这个问题:
股票名称: 贵州茅台
股票价格: 1850.0
股票代码: 600519.SH
根据使用场景选择合适的数据类型:
| 场景 | 推荐类型 | 理由 |
|---|---|---|
| 时间序列数据 | 列表 | 有序、可动态增删 |
| 键值对数据 | 字典 | O(1)快速查找 |
| 固定配置参数 | 元组 | 不可变、安全 |
| 去重数据 | 集合 | 自动去重 |
| 矩阵运算 | NumPy数组 | 高性能数值计算 |
选择原则:
import time
n = 1000000 # 100万元素
test_list = list(range(n))
test_dict = {i: f'value_{i}' for i in range(n)}
# 列表查找(O(n) - 需要逐个比较)
start = time.time()
result = 999999 in test_list
list_time = time.time() - start
# 字典查找(O(1) - 哈希直接定位)
start = time.time()
result = 999999 in test_dict
dict_time = time.time() - start
print(f'列表查找时间: {list_time:.6f}秒')
print(f'字典查找时间: {dict_time:.6f}秒')
if dict_time > 0:
print(f'性能提升: {list_time / dict_time:.1f}倍')列表查找时间: 0.007035秒
字典查找时间: 0.000000秒
import copy
# 嵌套列表(模拟投资组合持仓)
portfolio = [
['600519.SH', 100, 1850.00],
['000858.SZ', 200, 85.50]
]
# 浅拷贝:内层仍然共享引用
portfolio_shallow = portfolio.copy()
# 深拷贝:完全独立的副本
portfolio_deep = copy.deepcopy(portfolio)
# 修改原始数据
portfolio[0][2] = 1900.00
# 浅拷贝受影响(共享内层引用)
print(f'浅拷贝: {portfolio_shallow[0][2]}') # 1900.00
# 深拷贝不受影响(完全独立)
print(f'深拷贝: {portfolio_deep[0][2]}') # 1850.00浅拷贝: 1900.0
深拷贝: 1850.0
| 场景 | 方法 | 说明 |
|---|---|---|
| 简单列表(不含嵌套) | list.copy() 或 [:] |
浅拷贝即可 |
| 嵌套结构 | copy.deepcopy() |
必须深拷贝 |
| 简单字典 | dict.copy() |
浅拷贝 |
| 嵌套字典 | copy.deepcopy() |
必须深拷贝 |
记住:处理金融数据时,数据安全性至关重要。当数据结构包含嵌套时,始终使用深拷贝。
三大数据类型核心特征:
[] 创建
{} 创建
() 创建
关键要点:
copy.deepcopy()[商业大数据分析与应用]